<?php


namespace app\admin\services;


use app\admin\exception\BadRequestException;
use app\admin\exception\ModelNotFoundException;
use app\admin\jobs\UserWithdrawJob;
use app\common\facades\WechatPay;
use app\common\models\User;
use app\common\models\UserWithdraw;
use app\Request;
use Carbon\Carbon;
use think\facade\Queue;

class WithdrawService
{
    private $withdrawModel;

    public function __construct(UserWithdraw $withdrawModel)
    {
        $this->withdrawModel = $withdrawModel;
    }

    public function search(Request $request)
    {
        $model = $this->withdrawModel
            ->alias('withdraw')
            ->leftjoin('xiangji_users user', 'withdraw.user_id = user.id');

        $mobile = $request->get('mobile', '');
        if (!empty($mobile)){
            $model = $model->where('user.mobile', '=', $mobile);
        }
        $status = $request->get('status', '');
        if ($status != ''){
            $model = $model->where('withdraw.status', '=', $status);
        }

        return $model->field([
            'withdraw.*',
            'user.mobile'
        ])->paginate([
            'list_rows' => $request->get('limit', 10),
            'page' => $request->get('page', 1)
        ]);
    }

    /**
     * @todo 审核提现
     * @param Request $request  审核数据
     * @return bool 操作结果
     * @throws BadRequestException
     * @throws ModelNotFoundException
     */
    public function audit(Request $request, $id)
    {
        $withdraw = $this->show($id);

        if ($withdraw->status != 1) {
            throw new BadRequestException('该提现订单已提现或已驳回');
        }
        $status = $request->post('status', 1);
        // 审核失败
        if ($status == 0){
            return $withdraw->save([
                'status'        => $status,
                'fail_reason'   => $request->post('fail_reason', ''),
                'audit_time'    => time()
            ]);
        }
        // 审核成功
        $withdraw->save([
            'status'        => $status,
            'audit_time'    => time(),
        ]);
        // 加入微信打款队列
        //Queue::push(UserWithdrawJob::class, $withdraw->id, 'user_withdraw');
        // 同步打款
        return $this->withdraw($withdraw);
    }

    public function withdraw(UserWithdraw $withdraw)
    {
        try {
            // 执行打款任务
            $result = WechatPay::payToBalance($withdraw->openid, $withdraw->trade_no, $withdraw->amount);
            if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
                // 打款成功
                $data = [
                    'status'        => 3,
                    'back_data'     => json_encode($result),
                    'payment_no'    => $result['payment_no'],
                    'payment_time'  => Carbon::parse($result['payment_time'])->getTimestamp()
                ];
            } else {
                // 打款失败
                $data = [
                    'status'        => 0,
                    'back_data'     => json_encode($result),
                ];
                if ($result['return_code'] == 'FAIL'){
                    // 接口调用失败：网关错误
                    $data['fail_reason'] = $result['return_msg'];
                } else {
                    // 接口调用成功，业务处理失败
                    $data['fail_reason'] = $result['err_code_des'];
                }
            }
        } catch (\Exception $exception){
            $data = [
                'status'        => 0,
                'fail_reason'   => $exception->getMessage()
            ];
        }
        return $withdraw->save($data);
    }

    public function statistics(int $user_id)
    {
        return User::with(['walletLogs' => function($query){
            $query->order('id', 'desc');
        }, 'wallet'])->find($user_id);
    }

    /**
     * @todo 获取提现订单详情
     * @param int $id   提现订单ID
     * @return array|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function show(int $id)
    {
        $withdraw = $this->withdrawModel->find($id);
        if (!$withdraw){
            throw new ModelNotFoundException('不存在该提现申请信息');
        }
        return $withdraw;
    }

    public function delete($id)
    {
        return $this->show($id)->delete();
    }
}
